package com.mib.snmp;

import org.snmp4j.CommunityTarget;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.UserTarget;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.SecurityModels;
import org.snmp4j.security.SecurityProtocols;
import org.snmp4j.security.USM;
import org.snmp4j.security.UsmUser;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.DefaultUdpTransportMapping;

import java.io.IOException;

public class SnmpFactory {

    public static SnmpBuilder createSNMP(SnmpBuilder builder) {
        Snmp snmp;
        Target target;

        // 默认udp协议
        String protocol = builder.getDefaultProtocol() != null ? builder.getDefaultProtocol() : SnmpConstant.DEFAULT_PROTOCOL;
        // 默认161端口
        int port = builder.getPort() != null ? builder.getPort() : SnmpConstant.DEFAULT_PORT;
        // 默认读口令
        String community = builder.getCommunity() != null ? builder.getCommunity() : SnmpConstant.DEFAULT_COMMUNITY;
        // 构造Address
        Address address = GenericAddress.parse(protocol + ":" + builder.getIp() + "/" + port);

        try {
            snmp = new Snmp(new DefaultUdpTransportMapping());
            // 开始监听消息
            snmp.listen();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (builder.getVersion() == SnmpConstants.version3) {
            // V3认证用户名
            String securityName = builder.getSecurityName();
            USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
            SecurityModels.getInstance().addSecurityModel(usm);
            // 添加用户
            UsmUser user = new UsmUser(
                    new OctetString(securityName),
                    builder.getAuthGeneric(), new OctetString(builder.getAuthPass()),
                    builder.getPrivacyGeneric(), new OctetString(builder.getPrivacyPass()));
            snmp.getUSM().addUser(new OctetString(securityName), user);

            target = new UserTarget();
            // 设置安全级别
            target.setSecurityLevel(builder.getSecurityLevel().getSnmpValue());
            target.setSecurityName(new OctetString(securityName));
        } else{
            target = new CommunityTarget();
            ((CommunityTarget) target).setCommunity(new OctetString(community));
        }
        // 目标对象相关设置
        target.setAddress(address);
        target.setTimeout(3000);
        target.setRetries(0);
        target.setVersion(builder.getVersion());

        builder.setSnmp(snmp);
        builder.setTarget(target);

        return builder;
    }

}
